package gui.components.objectinfo.info;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

import combat.protocol.data.Order;
import combat.protocol.interfaces.OrderInt;
import combat.protocol.types.OrderType;

import lookandfeel.customButton;
import simulation.Connection;
import simulation.Data;

public class orderQueue extends JPanel implements Runnable{
	
	private static final long serialVersionUID = 1L;

	private static Thread _runner;
	
	private DefaultTableModel model;
	private static JTable table;
	private int ordersInQueue;
	private JLabel lbl_ordersInQueue;
	private String ordInQueDisplayText = "Orders in queue: ";
	private static ArrayList<OrderInt> allOrders;
	private int lastKnownOrderID = 0;
	private ArrayList<OrderInt> exportedArrayList;
	
	public ArrayList<OrderInt> getExportedArrayList(){
		return exportedArrayList;
	}
	public void setExportedArrayList(ArrayList<OrderInt> _newExport){
		this.exportedArrayList = _newExport;
	}
	private void setLastKnownOrderID(int _orderID){
		lastKnownOrderID = _orderID;
	}
	private int getLastKnownOrderID(){
		return lastKnownOrderID;
	}
	
	public void run() 
    {
	    while(true){
    		fillTable();
		}
	}

	public void setOrdersInQueue(int _total){
		ordersInQueue = _total;	
	}
	public int getOrdersInQueue(){
		return ordersInQueue;
	}
	
	public static void setOrder(OrderInt _newOrder)
	{
		allOrders.add(_newOrder);
	}
	
	public ArrayList<OrderInt> getOrder()
	{
		return allOrders;
	}
	
	public orderQueue(){	
		
		_runner = new Thread(this,"Data Thread");
    	_runner.start();
		
		generateTable();
	}
	private void generateTable(){
		//Remove button onclick event
		class removeFromQueue implements ActionListener
		{
			public void actionPerformed(ActionEvent event) {
				  if(table.getSelectedRow() != -1){
					  int selectedRow = table.getSelectedRow();
		    		  model.removeRow(selectedRow);
		    		  //If there are still items in the queue
		    		  if(model.getRowCount() > 0){
		    			  //If last row is removed select new last row
			    		  if(selectedRow == (model.getRowCount()))
			    		  {
			    			  table.changeSelection(model.getRowCount() -1, model.getRowCount() -1, false, false);
			    		  }
			    		  //Else select row on old position
			    		  else
			    		  {
			    			  table.changeSelection(selectedRow, selectedRow, false, false);
			    		  }
			    		  setOrdersInQueue(model.getRowCount());
		    		  }
		    		  else{
		    			  setOrdersInQueue(0);
		    		  }
		    		  lbl_ordersInQueue.setText(ordInQueDisplayText + getOrdersInQueue());
		    	  }	
			}
		}
		//MoveUp button onclick event
		class moveUpInQueue implements ActionListener
		{
			public void actionPerformed(ActionEvent event) {
				  if(table.getSelectedRow() != -1){
					 int selectedRow = table.getSelectedRow();
					 //If not already on the first place move up
					 if(selectedRow != 0){
						 //Move the row
						 model.moveRow(selectedRow, selectedRow, selectedRow - 1);
						 //Re-select the row
						 table.changeSelection(selectedRow - 1, 0, false, false);
					 }
		    	  }	
			}
		}
		//MoveDown button onclick event
		class moveDownInQueue implements ActionListener
		{
			public void actionPerformed(ActionEvent event) {
				  if(table.getSelectedRow() != -1){
					  int selectedRow = table.getSelectedRow();
						 //If not already on the last place move down
					  	 if(selectedRow != (model.getRowCount() - 1)){
					  		 //Move the row
							 model.moveRow(selectedRow, selectedRow, selectedRow + 1);
							//Re-select the row
							 table.changeSelection(selectedRow + 1, 0, false, false);
						 }
		    	  }	
			}
		}
		model = new DefaultTableModel();
	    model.addColumn("Type");
	    model.addColumn("Target");
	       
	    //Set orders in queue total
	    this.setOrdersInQueue(model.getRowCount());
	    lbl_ordersInQueue = new JLabel(ordInQueDisplayText + getOrdersInQueue());
	    //New table with the default table model
	    table = new JTable(model){
        	/**
			 * 
			 */
			private static final long serialVersionUID = 1L;

			public boolean isCellEditable(int rowIndex, int colIndex) {
      		  return false; //Disallow the editing of any cell
        	}
	    };
	    table.setPreferredSize(new Dimension(300, 200));
	    table.setPreferredScrollableViewportSize(table.getPreferredSize());
	    //turn of auto resize of table columns
	    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		TableColumn col = null;
		int prefSize = 0;
		//Define the column widths
		for(int i = 0; i < 2; i++){
			col = table.getColumnModel().getColumn(i);
			switch(i){
			case 0:
				prefSize = 40; //Column target
				break;
			case 1:
				prefSize = 160; //Column type
				break;
			default:
				prefSize = 50; //Default  
			};
			//Set the size
			col.setPreferredWidth(prefSize);
			//Disable resizable
			col.setResizable(false);
		}
	    //Single row selection
	    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
	    
	    //Get table header renderer
		final javax.swing.table.DefaultTableCellRenderer headerRenderer = 
			( ( javax.swing.table.DefaultTableCellRenderer )table.
			getTableHeader().getDefaultRenderer() );
		//Align headertext left
		headerRenderer.setHorizontalAlignment(SwingConstants.LEFT);
	    
	    //create buttons
	    customButton removeButton = new customButton("Remove Selected");
	    customButton moveUp = new customButton("Move up");
	    customButton moveDown = new customButton("Move down");
	    
	    //Add actionlisteners to buttons
	    removeButton.addActionListener(new removeFromQueue());
	    moveUp.addActionListener(new moveUpInQueue());
	    moveDown.addActionListener(new moveDownInQueue());
	    
	    JPanel inputPanel = new JPanel();
	    inputPanel.add(moveUp);
	    inputPanel.add(moveDown);
	    inputPanel.add(removeButton);
	    
	    JScrollPane tableContainer = new JScrollPane(table);
	    Dimension tableSize = table.getPreferredSize();
	    //Add same size of table to container + 18px width (scrollbar) padding
	    tableContainer.setPreferredSize(new Dimension(tableSize.width + 20, tableSize.height + 10));
	    this.add(inputPanel);
	    this.add(tableContainer);
	    lbl_ordersInQueue.setHorizontalAlignment(JLabel.RIGHT);
	    this.add(lbl_ordersInQueue);
	    model.addTableModelListener(new TableChangeEvent());
	}
	class TableChangeEvent implements TableModelListener{

		@Override
		public void tableChanged(TableModelEvent e) {
			exportTableToArrayList();
		}
		
	}
	public void exportTableToArrayList(){
		
		ArrayList<OrderInt> ordersPriority = new ArrayList<OrderInt>();
		int OrderID = 0;
		
		String tmpTypePart = null;
		Object tmpTarget = null;
		OrderType tmpType = null;
		//loop through every row
		for(int i = 0; i < table.getRowCount(); i++){
			OrderID++;
			//loop through every column
			for(int j = 0; j < table.getColumnCount(); j++){
				if(j == 0){
					tmpTypePart = table.getValueAt(i, j).toString();
				}
				else
				{
					tmpTarget = table.getValueAt(i, j);
				}
			}
			String MOVType = OrderType.MOV.toString();
			String ATKType = OrderType.ATK.toString();
			
			if(tmpTypePart.equals(MOVType))
			{
				tmpType = OrderType.MOV;
			}
				
			else if(tmpTypePart.equals(ATKType))
			{
				tmpType = OrderType.ATK;
			}
			//add the order to the orderspriorty ArrayList
			ordersPriority.add((OrderInt)new Order(tmpTarget, tmpType));
		}
	}
	
	public void fillTable()
	{
		try{
			ArrayList<OrderInt> newOrders = new ArrayList<OrderInt>();
			
			allOrders = Data.getVehicleOrders(Connection.getMe());
			
			//If table is empty add all rows
			if(model.getRowCount() == 0 && allOrders != null){
				int newOrderID = 0;
				
				for(OrderInt order : allOrders){
			    	order.setOrderID(newOrderID);
			    	//Add to model
			    	model.addRow(new Object[] {order.getType(), order.getTarget() });
			    	setLastKnownOrderID(newOrderID);
			    	//Increase orderID
			    	newOrderID++;
				}
			}
			//Loop through the orders to get new orders
			else{
				newOrders.clear();
				//Loop through allorders
				for(OrderInt order : allOrders){
					if(order.getOrderID() > getLastKnownOrderID()){
						newOrders.add(order);
					}
				}
				if(newOrders.size() > 0){
					for(OrderInt newOrder : newOrders){
						model.addRow(new Object[] {newOrder.getType(), newOrder.getTarget() });
						setLastKnownOrderID(newOrder.getOrderID());
					}
				}	
			}
			//If allorders size is not equal to model rowcount the server has completed an order
			if(allOrders.size() != model.getRowCount()){
				//remove the top order which the server finished executing
				model.removeRow(0);
			}
			lbl_ordersInQueue.setText(ordInQueDisplayText + model.getRowCount());
	    }
	    catch(Exception e){
	    	System.out.println(e.getMessage());
	    }
	}
}

